<?php
/*
 * @Author       : chaihao
 * @Date         : 2020-06-04 14:20:31
 * @FilePath     : /ai/Services/api/SendMessageService.php
 */

namespace app\Services\api;

use app\models\User;
use app\models\VerificationCode;
use app\Services\ApiService;
use TencentCloud\Common\Credential;
use Yii;


// 导入 SMS 的 client
use TencentCloud\Sms\V20190711\SmsClient;
// 导入要请求接口对应的 Request 类
use TencentCloud\Sms\V20190711\Models\SendSmsRequest;
use TencentCloud\Common\Exception\TencentCloudSDKException;
// 导入可选配置类
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use Yii\db\Exception;

class SendMessageService extends ApiService
{

    public function getSendNum($send_to){
        // 获取 1 分钟内邮件发送条数
       $count = VerificationCode::find()->where(['send_to' => $send_to])
       ->andWhere(['between', 'createtime',date('Y-m-d H:i:s',(time()-60)), date('Y-m-d H:i:s', time())])->count();
        if($count >= 5){ // 1分钟内最多5条
            return ['code' => -1 , 'message' => '邮件发送已达上线，请稍后发送'];
        }
        // 获取 今日 内邮件发送条数
        $today_count = VerificationCode::find()->where(['send_to' => $send_to])
        ->andWhere(['between', 'createtime', date('Y-m-d 00:00:00', time()),date('Y-m-d 23:59:59', time())])->count();
        if ($today_count >= 10) { // 每日最多10条
            return ['code' => -1, 'message' => '今日邮件发送已达上限'];
        }
        return ['code' => 200,'message'=> '邮件发送数量上限验证通过'];
    }


    public function insertLog($data)
    {
        $where = [];
        if (isset($data['cellphone']) && !empty($data['cellphone'])) {
            $where['username'] =  $data['cellphone'];
        } elseif (isset($data['email']) && !empty($data['email'])) {
            $where['email'] =  $data['email'];
        } else {
            return ['code' => -1, 'msg' => '账号错误'];
        }
        // 验证账号是否已存在
        $userInfo = User::find()->where($where)->asArray()->one();
        if ($data['type'] == 1) {
            if (!empty($userInfo)) {
                return ['code' => -1, 'msg' => '账号已存在'];
            }
        } else {
            if (empty($userInfo)) {
                return ['code' => -1, 'msg' => '账号不存在'];
            }
        }
        $info = [
            'code' => $data['code'],
            'type' => (int) $data['type'],
            'send_to' => trim($data['send_to']),
            'userID' => $userInfo['ID'] ?? NULL,
            'createtime' => date('Y-m-d H:i:s', time()),
            'updatetime' => date('Y-m-d H:i:s', time()),
            'validtime' => $data['validtime'],
            'is_send' => 0,
        ];
        try {
            // 保存验证信息
            Yii::$app->db->createCommand()->insert(VerificationCode::tableName(), $info)->execute();
            return ['code' => 200, 'message' => '添加成功'];
        } catch (Exception $e) {
            return ['code' => -1, 'message' => $e->getMessage()];
        }
    }



    public function updateLogStatus($info)
    {
        Yii::info($info, '$info');
        // 修改验证信息消息发送
        try {
            // 修改验证信息消息发送状态
            Yii::$app->db->createCommand()->update(
                VerificationCode::tableName(),
                ['is_send' => 1],
                ['send_to' => trim($info['send_to']), 'code' => $info['code'], 'createtime' => $info['createtime']]
            )->execute();
            return ['code' => 200, 'message' => '操作成功'];
        } catch (Exception $e) {
            return ['code' => -1, 'message' => $e->getMessage()];
        }
    }


    /**
     * 发送验证码
     *
     * @param [type] $data 数据
     * @param [type] $send_type 消息类型（mobile ， email）
     */
    public function send($data, $send_type)
    {
        // 生成验证码
        $code = mt_rand(100000, 999999);
        $minute = $data['validtime']  ?? 3; // 定义有效时间
        // 验证账号是否已存在
        $userInfo = User::find()->where(['username' => trim($data['username'])])->asArray()->one();
        if ($data['type'] == 1) {
            $typeName = '注册';
            if (!empty($userInfo)) {
                return ['code' => -1, 'msg' => '账号已存在'];
            }
        } else {
            $typeName = '登录';
            if (empty($userInfo)) {
                return ['code' => -1, 'msg' => '账号不存在'];
            }
        }
        $info = [
            'code' => $code,
            'type' => (int) $data['type'],
            'userID' => $userInfo['ID'] ?? NULL,
            'send_to' => trim($data['username']),
            'createtime' => date('Y-m-d H:i:s', time()),
            'updatetime' => date('Y-m-d H:i:s', time()),
            'validtime' => $minute,
            'is_send' => 0,
        ];
        if ($send_type == 'mobile') {
            if (!preg_match("/^1[345789]\d{9}$/", $data['username'])) {
                return ['code' => -1, 'msg' => '手机号格式不合法'];
            }
        }
        try {
            // 保存验证信息
            Yii::$app->db->createCommand()->insert(VerificationCode::tableName(), $info)->execute();
        } catch (Exception $e) {
            return ['code' => -1, 'message' => $e->getMessage()];
        }
        // 发送消息
        if ($send_type == 'mobile') {
            $template = Yii::$app->params['secretLoginTemplateID'];
            if ($data['type'] == 1) {
                $template = Yii::$app->params['secretRegisteredTemplateID'];
            }
            $result =  $this->sendSms($data['username'], $template, $code, $minute);
            // 单次发送一个手机号，只存在一条返回结果
            $msInfo = json_decode($result, true);
            $messageInfo =  $msInfo['SendStatusSet'][0];
            if (!$messageInfo['Fee'] || $messageInfo['Code'] != 'Ok') {
                return ['code' => -1, 'message' => $messageInfo['Message']];
            }
        } else {
            $content = '<b>【上海东方传媒技术有限公司】您正在申请' . $typeName . '，验证码为：<b style="font-size:20px">' . $code . '</b>，' . $minute . '分钟内有效！</b>';
            $result =  $this->sendEmail($data['username'], '上海东方传媒技术有限公司' . $typeName, $content);
            if (!$result) {
                return ['code' => -1, 'message' => '邮件发送失败'];
            }
        }
        // 修改验证信息消息发送
        try {
            // 修改验证信息消息发送状态
            Yii::$app->db->createCommand()->update(
                VerificationCode::tableName(),
                ['is_send' => 1],
                ['send_to' => trim($data['username']), 'code' => $info['code'], 'createtime' => $info['createtime']]
            )->execute();
            return ['code' => 200, 'message' => '操作成功'];
        } catch (Exception $e) {
            return ['code' => -1, 'message' => $e->getMessage()];
        }
    }

    public function sendEmail($toMember, $subject, $body)
    {
        // 构造对象
        $emailObj = Yii::$app->mailer->compose();
        // 设置发件人的邮箱地址
        return $emailObj->setTo($toMember)
            ->setSubject($subject)
            ->setHtmlBody($body)
            // ->setTextBody($body)
            ->send();
    }


    public function sendSms($username, $template, $verification_code, $valid_time)
    {
        try {
            /* 必要步骤：
            * 实例化一个认证对象，入参需要传入腾讯云账户密钥对secretId，secretKey。
            * 这里采用的是从环境变量读取的方式，需要在环境变量中先设置这两个值。
            * 你也可以直接在代码中写死密钥对，但是小心不要将代码复制、上传或者分享给他人，
            * 以免泄露密钥对危及你的财产安全。
            * CAM密匙查询: https://console.cloud.tencent.com/cam/capi
            */

            $cred = new Credential(Yii::$app->params['secretId'], Yii::$app->params['secretKey']);
            // $cred = new Credential(getenv("TENCENTCLOUD_SECRET_ID"), getenv("TENCENTCLOUD_SECRET_KEY"));

            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            $httpProfile = new HttpProfile();
            $httpProfile->setReqMethod("GET");  // post请求(默认为post请求)
            $httpProfile->setReqTimeout(30);    // 请求超时时间，单位为秒(默认60秒)
            $httpProfile->setEndpoint("sms.tencentcloudapi.com");  // 指定接入地域域名(默认就近接入)

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            $clientProfile = new ClientProfile();
            $clientProfile->setSignMethod("TC3-HMAC-SHA256");  // 指定签名算法(默认为HmacSHA256)
            $clientProfile->setHttpProfile($httpProfile);

            // 实例化要请求产品(以sms为例)的client对象,clientProfile是可选的
            $client = new SmsClient($cred, "ap-shanghai", $clientProfile);

            // 实例化一个 sms 发送短信请求对象,每个接口都会对应一个request对象。
            $req = new SendSmsRequest();

            /* 填充请求参数,这里request对象的成员变量即对应接口的入参
     * 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
     * 基本类型的设置:
	 * 帮助链接：
	 * 短信控制台: https://console.cloud.tencent.com/sms/smslist
	 * sms helper: https://cloud.tencent.com/document/product/382/3773 */

            /* 短信应用ID: 短信SdkAppid在 [短信控制台] 添加应用后生成的实际SdkAppid，示例如1400006666 */
            $req->SmsSdkAppid = "1400381029";
            /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名，签名信息可登录 [短信控制台] 查看 */
            $req->Sign = Yii::$app->params['secretSign'];
            /* 短信码号扩展号: 默认未开通，如需开通请联系 [sms helper] */
            $req->ExtendCode = "0";
            /* 下发手机号码，采用 e.164 标准，+[国家或地区码][手机号]
	 * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号*/
            $req->PhoneNumberSet = array("+86" . $username);
            /* 国际/港澳台短信 senderid: 国内短信填空，默认未开通，如需开通请联系 [sms helper] */
            $req->SenderId = "";
            /* 用户的 session 内容: 可以携带用户侧 ID 等上下文信息，server 会原样返回 */
            $req->SessionContext = 'username:' . $username . '；code:' . $verification_code;
            /* 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看 */
            $req->TemplateID = $template;
            /* 模板参数: 若无模板参数，则设置为空*/
            $req->TemplateParamSet = array($verification_code, $valid_time);


            // 通过client对象调用DescribeInstances方法发起请求。注意请求方法名与请求对象是对应的
            // 返回的resp是一个DescribeInstancesResponse类的实例，与请求对象对应
            $resp = $client->SendSms($req);

            // 输出json格式的字符串回包
            return $resp->toJsonString();

            // 也可以取出单个值。
            // 你可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义
            // print_r($resp->TotalCount);
        } catch (TencentCloudSDKException $e) {
            echo $e;
        }
    }
}
